package chapter6;

import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.*;

/**
 * @author caiya
 * @date 2020/3/31 20:23
 */
@Slf4j
public class ScheduledThreadPoolExecutorTest {
    static ScheduledThreadPoolExecutor scheduleThreadPoolExecutor = new ScheduledThreadPoolExecutor(3,
            Executors.defaultThreadFactory(), new ThreadPoolExecutor.CallerRunsPolicy());

    public static void main(String[] args) {
        /**
         * ScheduledThreadPoolExecutor：继承自ThreadPoolExecutor，线程池队列是DelayedWorkQueue，和DelayedQueue类似，具备延迟功能，最大线程数为Integer.MAX_VALUE
         * 1、线程池的几种状态：
         *      1）NEW：初始状态
         *      2）COMPLETING：执行中
         *      3）NORMAL：正常运行的结束状态
         *      4）EXCEPTIONAL：运行中异常
         *      5）CANCELLED：任务被取消
         *      6）INTERRUPTING：任务正在被中断
         *      7）INTERRUPTED：任务被中断
         * 2、ScheduledThreadPoolExecutor使用内部period变量标识任务类型：
         *      1）period = 0：一次性任务，执行完毕就结束
         *      2）period < 0：fixed-delay任务，是固定延迟的定时可重复任务
         *      3）period > 0：fixed-rate任务，固定频率的定时可重复任务
         * 3、三个重要的方法：
         *      1）ScheduledFuture<?> schedule(Runnable command, long delay, TimeUnit unit)：提交一个一次性任务，该任务延迟delay时间后执行。对应 period = 0，
         *          delay：延迟的时间
         *      2）ScheduledFuture<?> scheduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit)：提交一个fixed-delay任务，其中，
         *          initialDelay：提交任务到线程池后多久开始执行command，
         *          delay：任务执行完毕后延长delay时间再次执行command，强调的是任务执行结束后延迟delay再执行，如此往复
         *      3）ScheduledFuture<?> scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit)：提交一个fixed-rate任务，其中，
         *          initialDelay：多久后开始执行command，
         *          period：command执行的间隔，强调的是任务执行的时间点，比如每次任务启动时间点为：initialDelay+period、initialDelay+2period、initialDelay+3period...
         *              备注：如果本次执行的时间点到达但是上次任务还未执行结束，则本次任务会延迟执行直到上次任务执行结束。
         */

        log.debug("now started!");

        // 一次性任务，10s后执行
        scheduleThreadPoolExecutor.schedule(new Runnable() {
            @Override
            public void run() {
                log.debug(Thread.currentThread().getName() + "【一次性任务】");
            }
        }, 10, TimeUnit.SECONDS);

        // fixed-delay任务：1s后执行任务，完了每次任务执行结束延迟5s再次执行
        scheduleThreadPoolExecutor.scheduleWithFixedDelay(new Runnable() {
            @Override
            public void run() {
                log.debug(Thread.currentThread().getName() + "【fixed-delay：1s、5s】");
            }
        }, 1, 5, TimeUnit.SECONDS);

        // fixed-rate任务，2s后开始执行，而后每隔7s执行一次
        scheduleThreadPoolExecutor.scheduleAtFixedRate(new Runnable() {
            @Override
            public void run() {
                log.debug(Thread.currentThread().getName() + "【fixed-rate：2s、7s】");
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }, 2, 7, TimeUnit.SECONDS);
    }
}
